package com.h2cloud.aspect.runtimeEx;

import com.h2cloud.depends.MessageException;
import com.h2cloud.depends.Response;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.util.Objects;

/**
 * @author: wulongkai
 * @create: 2022-08-27 00:57
 **/
@Slf4j
//@Aspect
//@Component
public class ExceptionAspect {

    //    @Pointcut("execution(* com.h2cloud.test.testRuntimeEx.WorkFlowBizService.*(..))")
    @Pointcut("@within(com.h2cloud.aspect.runtimeEx.ExceptionResponse)") // 注解加在类上，类中的所有方法都能拦截
//    @Pointcut("@annotation(com.h2cloud.test.testRuntimeEx.ExceptionResponse)") // 注解加在方法上，才会识别到
    public void getPointcut() {
    }

    @Around("getPointcut()")
    public Object around(ProceedingJoinPoint point) {
        System.out.println("aspect start");
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        Class<?> declaringType = methodSignature.getDeclaringType();
        String fullClassName = declaringType.getName();
        int idx = fullClassName.lastIndexOf('.');
        // 类名
        String className = fullClassName.substring(idx + 1);
        // 方法名
        String methodName = methodSignature.getName();
        // 参数名
        String[] parameterNames = methodSignature.getParameterNames();
        // 参数
        Object[] args = point.getArgs();
        StringBuilder logBuilder = new StringBuilder(className + "-" + methodName);
        if (Objects.nonNull(parameterNames) && parameterNames.length != 0) {
            logBuilder.append(" [");
            for (int i = 0; i < parameterNames.length; i++) {
                String parameterName = parameterNames[i];
                Object arg = args[i];
                logBuilder.append(parameterName).append("=").append(arg);
                if (i < parameterNames.length - 1) {
                    logBuilder.append(", ");
                }
            }
            logBuilder.append("]");
        }
        log.info(logBuilder.toString());

        Object obj = null;
        String msg = null;
        Throwable o = null;
        try {
            obj = point.proceed();
        } catch (IllegalArgumentException | MessageException runtimeException) {
            msg = runtimeException.getMessage();
            o = runtimeException;
        } catch (Throwable throwable) {
            msg = throwable.getMessage();
            o = throwable;
        }
        if (Objects.nonNull(o)) {
            log.error(msg, o);
            obj = Response.getFailureResult(msg);
        }
        return obj;
    }
}
